#include <stdint.h>
#include <stddef.h>

void tree_init(void);
uint8_t tree_print(uint8_t * pc, uint32_t len);

uint8_t ret;
uint8_t * pnc; //pNodeChar

int main(void)
{
    pnc = NULL;
    uint8_t cmd1[] = {'B','T','X'};
    uint8_t cmd2[] = {'C','U','Z'};
    
    tree_init();
    
    ret = tree_print(cmd1,3);
    
    ret = tree_print(cmd2,3);
    
    for(;;);
    return ret;
}

/*
///////////// type define //////////////
*/ 
typedef struct CharNodeHeader {
    uint8_t chr; //Char
    uint8_t ind; //Func id(12bit)
    uint16_t snb; //sub node number(12bit)
} Cin_t;

#define GET_SNB(p) ( (uint16_t)(((p)->snb)>>4) )
#define GET_IND(p) ( ((((p)->snb)<<8)&0x0F00) | ((uint16_t)((p)->ind)&0x0FF) )


struct CharNodeClass1 {
    union{
        uint32_t h;
        Cin_t cin; //Char Id Number
    } u;
    Cin_t *sub1;
};


// TODO: struct CharNodeClassN

/*
///////////// global define //////////////
*/ 
//level 1
struct CharNodeClass1 lv1_1;
struct CharNodeClass1 lv1_2;

//level 2
struct CharNodeClass1 lv2_1;
struct CharNodeClass1 lv2_2;

//level 3
struct CharNodeClass1 lv3_1;
struct CharNodeClass1 lv3_2;

void tree_init(void)
{
//cmd1 ----------------------------------
    lv1_1.u.cin.chr = 'B';
    lv1_1.u.cin.snb = 1;
    lv1_1.sub1 = &lv2_1.u.cin;
    
    lv2_1.u.cin.chr = 'T';
    lv2_1.u.cin.snb = 1;
    lv2_1.u.cin.ind = 3;
    lv2_1.sub1 = &lv3_1.u.cin;

    lv3_1.u.cin.chr = 'X';
    lv3_1.u.cin.snb = 1;
    lv3_1.u.cin.ind = 4;
    lv3_1.sub1 = NULL;
    
    uint16_t ind31 = GET_IND(&lv3_1.u.cin); //test GET_IND
    uint16_t snb31 = GET_SNB(&lv3_1.u.cin); //test GET_SNB
    snb31 = ind31 = ind31+snb31; //do dummy ops after a fashion
//cmd2 ----------------------------------
    lv1_2.u.cin.chr = 'C';
    lv1_2.u.cin.snb = 1;
    lv1_2.sub1 = &lv2_2.u.cin;
    
    lv2_2.u.cin.chr = 'U';
    lv2_2.u.cin.snb = 1;
    lv2_2.u.cin.ind = 6;
    lv2_2.sub1 = &lv3_2.u.cin;
    
    lv3_2.u.cin.chr = 'Z';
    lv3_2.u.cin.snb = 1;
    lv3_2.u.cin.ind = 8;
    lv3_2.sub1 = NULL;
}

uint8_t tree_print(uint8_t * pc, uint32_t len)
{
//    static uint8_t * pnc = NULL; //pNodeChar
    uint8_t retn;
    
    if (pnc != NULL) {
        if (*pnc == *pc)
        {
            Cin_t *c = (Cin_t *)pnc;
            
            if ((len-1) > 0) {
                struct CharNodeClass1 * cnc1 = (struct CharNodeClass1 *)c;
                if (cnc1->sub1 != NULL) {
                    
                    pnc = (uint8_t *)cnc1->sub1;
                    retn = tree_print(pc+1,len-1);
                    
                }else{
                    retn = 0xff;
                }
            }else{
                retn = c->ind;
            }
        }
        else{
            retn = 0xff;
        }
        pnc = NULL;
    }
    else{
        if (lv1_1.u.cin.chr == *pc)
        {
            //1 ----------------------------------
            if ((len-1) > 0) {
                if (lv1_1.sub1 != NULL) {
                    
                    pnc = (uint8_t *)lv1_1.sub1;
                    retn = tree_print(pc+1,len-1);
                    
                }else{
                    return 0xff;
                }
            }else{
                return lv1_1.u.cin.ind;
            }
            //1 ----------------------------------
        }
        else if (lv1_2.u.cin.chr == *pc)
        {
            //2 ----------------------------------
            if ((len-1) > 0) {
                if (lv1_2.sub1 != NULL) {
                    
                    pnc = (uint8_t *)lv1_2.sub1;
                    retn = tree_print(pc+1,len-1);
                    
                }else{
                    return 0xff;
                }
            }else{
                return lv1_2.u.cin.ind;
            }
            //2 ----------------------------------
        }else{
            return 0xff;
        }
    }
    return retn;
}
